<?php
class Shop_Model_Product extends Promotor_Model_Scaffold {

	protected $_dbTableClass = 'Shop_Model_DbTable_Product';
	
	protected $_cachedMethods = array(
		'findById',
		'findByIdAllInfo',
		'findByAlias',
		'findAllInCategory',
		'findAllForManufacturer',
		'getAttachedCategoriesId'
	);
	
	public function selectList() {
		$db = $this->getDbTable()
				   ->getAdapter();

		$select = new Zend_Db_Select($db);
		
		$select->from(array('shc' => 'shop_has_category'))
			   ->joinInner(
			   		array('sp' => 'shop_product'),
			   		'shc.product_id = sp.id',
			   		array(
			   			'*',
			   			'promotion' => new Zend_Db_Expr('CURRENT_DATE BETWEEN spp.t_start AND spp.t_end')
			   		)
			   	)

			   	->joinLeft(
			   		array('sc' => 'shop_category'),
			   			'sc.id = shc.category_id', array('category' => 'name'))
			   	
			   	->joinLeft(
			   		array('sm' => 'shop_manufacturer'),
			   			'sp.manufacturer_id = sm.id', array('manufacturer' => 'name'))

			   	->joinLeft(
			   		array('spp' => 'shop_promotion'),
			   		'spp.product_id = sp.id',
			   		array('modifer','value'));
			   		
		return $select;
	}
	
	/**
	 * @param integer $productId
	 * @param integer $imageId
	 * @return unknown_type
	 */
	public function setMainImage($productId, $imageId)
	{
		if (!is_numeric($productId) && !is_numeric($imageId))
		{
			$this->_setStatus(self::FAILURE);
			return;
		}

		$row = $this->findById($productId, false);

		if ($this->getStatus() !== self::SUCCESS) {
			$this->_setStatus(self::FAILURE);
			$this->_addMessage('Record do not exsists');
			return false;
		}
			
		try {
			$row->image_id = $imageId;
			$row->save();
			$this->_setStatus(self::SUCCESS);
		} catch (Zend_Db_Exception $e) {
			$this->_setStatus(self::FAILURE);
			$this->_addMessage($e->getMessage());
		}
	}

	/**
	 * @param int|string $identification
	 */
	public function findByIdAllInfo($identification) {
		$db = $this->getDbTable()->getAdapter();

		$select = new Zend_Db_Select($db);
		$select->from(
				array('sp' => 'shop_product'),
				array(
		   			'*',
		   			'promotion' => new Zend_Db_Expr('CURRENT_DATE BETWEEN spp.t_start AND spp.t_end')
		   		)
		   	)
			->joinLeft(
			   		array('spp' => 'shop_promotion'),
			   		'spp.product_id = sp.id',
			   		array('modifer','value'))

			->where('spp.t_end IS NULL OR CURRENT_DATE BETWEEN spp.t_start AND spp.t_end')
			->limit(1);
			
		if (is_integer($identification)) {
			$select->where('sp.id = ?', $identification);
		} elseif (is_string($identification)) {
			$select->where('sp.alias = ?', $identification);
		}
		
		$data = null;
		
		try {
			$stmt = $select->query();
			$data = $stmt->fetch();
		} catch (Zend_Db_Exception $e) {
			$this->_addException($e);
		}
		
		return $data;
	}
	
	/**
	 * @param integer $id
	 * @param bool $asArray
	 * @return array|Zend_Db_Tabler_Row_Abstract
	 */
	public function findById($id, $asArray = true) {
		$table = $this->getDbTable();

		try {
			$rowset = $table->find((int) $id);
			if(!count($rowset)) {
				$this->_setStatus(self::FAILURE);
				return;
			}

			$this->_setStatus(self::SUCCESS);

			$row = $rowset->current();
			$image = $row->findParentRow('Shop_Model_DbTable_Image');

			// jako tablica dodawany jest klucz z grafiką :)
			if ($asArray) {
				$row = $row->toArray();
				$row['image'] = (null === $image) ? null : $image->toArray() ;
			}

			return $row;
		} catch (Zend_Db_Table_Exception $e) {
			$this->_setStatus(self::FAILURE);
			$this->_addMessage($e->getMessage());
		}
	}
	
	/**
	 * @param string $alias
	 * @param bool $asArray
	 * @return array|Zend_Db_Tabler_Row_Abstract
	 */
	public function findByAlias($alias, $asArray = true) {
		$table = $this->getDbTable();
		$where = $table->getAdapter()->quoteInto('alias = ?', $alias);

		try {
			$row = $table->fetchRow($where);
			if(!$row instanceof Zend_Db_Table_Row_Abstract) {
				$this->_setStatus(self::FAILURE);
				return;
			}

			$this->_setStatus(self::SUCCESS);

			$image = $row->findParentRow('Shop_Model_DbTable_Image');

			// jako tablica dodawany jest klucz z grafiką :)
			if ($asArray) {
				$row = $row->toArray();
				$row['image'] = (null === $image) ? null : $image->toArray() ;
			}

			return $row;
		} catch (Zend_Db_Table_Exception $e) {
			$this->_setStatus(self::FAILURE);
			$this->_addException($e);
		}
	}
	
	/**
	 * @param Zend_Db_Table_Row_Abstract|array|integer $category
	 * @param integer $page
	 * @param integer $onPage
	 * @return array
	 */
	public function findAllInCategory($category = null,  $page = null, $onPage = null) {
		if (is_numeric($category)) {
			$category = (int) $category;
		} elseif ($category instanceof Zend_Db_Table_Row_Abstract) {
			$category = $category->id;
		} elseif (is_array($category)) {
			$category = isset($category['id'])
				? $category['id']
				: (isset($category['category_id']) ? $category['category_id'] : null);
		}

		$table = $this->getDbTable();
		$db = $table->getAdapter();

		$select = new Zend_Db_Select($db);
		$select->from(array('shc' => 'shop_has_category'), array())
			   ->joinInner(
			   		array('sp' => 'shop_product'),
			   		'shc.product_id = sp.id',
			   		array(
			   			'*',
			   			'promotion' => new Zend_Db_Expr('CURRENT_DATE BETWEEN spp.t_start AND spp.t_end')
			   		)
			   	)

			   	// tylko produkty gdzie producent jest widoczny
			   	->joinInner(
			   		array('sm' => 'shop_manufacturer'),
			   		'sm.id = sp.manufacturer_id ',
//			   		'AND sm.publicated = 1',
			   		array())
			   	
			   	// tylko produkty gdzie kategoria jest widoczna
			   	->joinInner(
			   		array('sc' => 'shop_category'),
			   		'sc.id = shc.category_id ',
//			   		'AND sc.publicated = 1',
			   		array())

			   	// czy produkt jest w promocji
			   	->joinLeft(
			   		array('spp' => 'shop_promotion'),
			   		'spp.product_id = sp.id',
			   		array('modifer','value'))

			   	// dołączenie grafiki głównej
			   	->joinLeft(
			   		array('si' => 'shop_image'),
			   		'si.id = sp.image_id',
			   		array('image_name' => 'name','image'))

			   	// gdzie produkt jest publikowany
			   	->where('sp.publicated = 1')
			   	
			   	// gdzie producent jest widoczny
			   	->where('sm.publicated = 1')

			   	// gdzie kategoria jest widoczna
			   	->where('sc.publicated = 1')

			   	// tylko produkty które nie są w produkcji lub produkty których prmocja jest w przedziale
			   	->where('spp.t_end IS NULL OR CURRENT_DATE BETWEEN spp.t_start AND spp.t_end')

			   	// sortuowanie od najmniejszej wartosci do największej
			   	->order('shc.idx ASC');
			   	
		if (null !== $category) {
			$select->where('shc.category_id = ?', $category, Zend_Db::INT_TYPE);
		} else {
			$select->distinct(true);
		}
		
		if (is_numeric($page) && is_numeric($onPage)) {
			$select->limitPage($page, $onPage);
		}

		try {
			$stmt = $select->query();
			$rowset = $stmt->fetchAll();
			$this->_setStatus(self::SUCCESS);
			return array($rowset, $select);
		} catch(Zend_Date_Exception $e) {
			$this->_addException($e);
			$this->_setStatus(self::FAILURE);
		}
	}
	
	/**
	 * @param Zend_Db_Table_Row_Abstract|array|integer $manufacturer
	 * @param integer $page
	 * @param integer $onPage
	 * @return array
	 */
	public function findAllForManufacturer($manufacturer,  $page = null, $onPage = null) {
		if (is_numeric($manufacturer)) {
			$manufacturer = (int) $manufacturer;
		} elseif ($manufacturer instanceof Zend_Db_Table_Row_Abstract) {
			$manufacturer = $manufacturer->id;
		} elseif (is_array($manufacturer)) {
			$manufacturer = isset($manufacturer['id'])
				? $manufacturer['id']
				: (isset($manufacturer['manufacturer_id']) ? $manufacturer['manufacturer_id'] : null);
		}

		$table = $this->getDbTable();
		$db = $table->getAdapter();

		$select = new Zend_Db_Select($db);
		$select->from(array('sp' => 'shop_product'))
		
				// dołaczenie producenta, wiem że maszło maślane
			   	->joinInner(
			   		array('sm' => 'shop_manufacturer'),
			   		'sm.id = sp.manufacturer_id',
			   		array())

			   	// dołączenie grafiki głównej
			   	->joinLeft(
			   		array('si' => 'shop_image'),
			   		'si.id = sp.image_id',
			   		array('image_name' => 'name','image'))

			   	->where('sp.manufacturer_id = ?', $manufacturer, Zend_Db::INT_TYPE)
			   	->where('sp.publicated = 1')

			   	// tylko produkty gdzie producent jest widoczny
			   	->where('sm.publicated = 1')
			   	->order('sp.name ASC');
		
		if (is_numeric($page) && is_numeric($onPage)) {
			$select->limitPage($page, $onPage);
		}

		try {
			$stmt = $select->query();
			$rowset = $stmt->fetchAll();
			$this->_setStatus(self::SUCCESS);
			return array($rowset, $select);
		} catch(Zend_Date_Exception $e) {
			$this->_addException($e);
			$this->_setStatus(self::FAILURE);
		}
	}

	/**
	 * @param mixed $productPK
	 * @return array
	 */
	public function getAttachedCategoriesId($productPK) {
		$table = $this->getDbTable();

		// resetowanie kluczy dla $table->find()
		$productPK = array_values($productPK);
		
		try {
			$row = $table->find($productPK)
						 ->current();

		} catch (Zend_Db_Exception $e) {
			$this->_addException($e);
			$this->_setStatus(self::FAILURE);
			return;
		}
		
		if (!$row instanceof Zend_Db_Table_Row_Abstract) {
			$this->_setStatus(self::FAILURE);
			return;
		}

		try {
			$rowset = $row->findDependentRowset(
				'Shop_Model_DbTable_HasCategory'
			);
		} catch (Zend_Db_Exception $e) {
			$this->_addException($e);
			$this->_setStatus(self::FAILURE);
			return;
		}
		
		$return = array();
		foreach ($rowset as $row) {
			$return[] = $row->category_id;
		}

		$this->_setStatus(self::SUCCESS);
		return $return;
	}
}